package com.rfsp.common.controller;

import com.rfp.ws.utils.ECCUtils;
import com.rfsp.common.base.BaseController;
import com.rfsp.common.pojo.po.LoginPO;
import com.rfsp.common.pojo.po.OrgPO;
import com.rfsp.common.pojo.po.UserPO;
import com.rfsp.common.service.*;
import com.rfsp.mcp.pojo.po.AgreementRecordPO;
import com.rfsp.common.shiro.ShiroUtils;
import com.rfsp.common.util.JsonUtil;
import com.rfsp.common.enums.SystemConst;
import com.rfsp.common.util.ValidUtil;
import com.rfsp.common.pojo.vo.PrivilegeVO;
import com.rfsp.mcp.service.*;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.SimpleAccountRealm;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.*;

@Controller
@RequestMapping("/login")
public class LoginController extends BaseController {

	private static final Logger log = LoggerFactory.getLogger(LoginController.class);
	
	@Autowired
	OrgService orgService;
	@Autowired
	UserService userService;
	@Autowired
	ParamService paramService;
	@Autowired
	PriviService permService;
	@Autowired
	LoginService loginService;
	@Autowired
	RecordService recordService;

    @Value("${server.servlet.session.timeout}")
	int timeOut;

	@RequestMapping("/developing")
	public String newQuery(ModelMap model) {
		return "/base/tips/actionResult4developing";
	}

	@RequestMapping("/actionResult")
	public String actionResult(ModelMap model) {
		
		model.put("messageTitle", "提示信息:");
		model.put("messageContext", "您存在未结清的业务，如变更资金方，请确认已结清贷款并在平台撤销授权（操作路径：申请融资记录-撤销授权），经原资金方同意后，再继续向其他资金方申请融资。");
		return "/base/tips/actionResult";
	}

	ModelAndView error(ModelMap model, String errorMsg) {
		model.put("errMsg", errorMsg);
		return new ModelAndView("index");
	}
	ModelAndView errorLogin(ModelMap model) {
        model.putIfAbsent("errMsg", "用户名或密码错误");
		if(paramService.isDev()) {
			return new ModelAndView("index");
		}
		return redirectView("/error/notLogin");
	}
	
	//用户无权限跳转
	@RequestMapping("/rfpLogin")
	public ModelAndView rfpLogin(ModelMap model, HttpServletRequest request) {

		String token = request.getParameter("token");
        log.info("-------------token=------------{}", token);
		if(StringUtils.isBlank(token)) {
			return errorLogin(model);
		}else {
			token = token.replaceAll(" ", "+");
			log.info("-------------token2=------------{}", token);
		}
		LoginPO loginPO = null;
		try {
			String keyPath = paramService.getValue("system_key_path");
            log.info("-------------keyPath=------------{}", keyPath);
			String oldStrEcc = ECCUtils.decrypt(token, keyPath);
            log.info("-------------oldStrEcc=------------{}", oldStrEcc);
			loginPO = JsonUtil.toBean(oldStrEcc, LoginPO.class);
			Long id = loginPO.getId();
			LoginPO tmp = loginService.get(id);
			if(loginPO.getToken().trim().equals(tmp.getToken().trim())) {
				if("0".equals(tmp.getStatus())) {
					loginPO.setStatus("1");
					loginService.update(loginPO);
				}else {
					return errorLogin(model);
				}
			}else {
				return errorLogin(model);
			}
		} catch (Exception e1) {
			log.error(e1.getMessage(), e1);
		}
		String sessionId = userService.getUserSession(loginPO.getUserCode());
		if(ValidUtil.isEmpty(sessionId)) {
			model.put("errMsg", "用户session异常");
			return errorLogin(model);
		}

		UserPO user = userService.getUser(loginPO.getUserCode());
		if(user == null) return errorLogin(model);
		return loginInit(request, model, user, user.getPassword(), "1", loginPO.getToken(), sessionId);
	}

	public ModelAndView loginInit(HttpServletRequest request,  ModelMap model, UserPO user, String password,String loginType, String loginToken, String sessionId) {

		OrgPO org = orgService.get(user.getOrgId());
		if(org ==null) return errorLogin(model);
		List<String> roleSet = userService.queryRolesByUser(user.getUserCode());
		if(null==roleSet || roleSet.isEmpty()) return errorLogin(model);
		if(!roleSet.contains("mcp_bank") && !roleSet.contains("mcp_hos")) return errorLogin(model);

		ShiroUtils.kickOutUser(user.getUserCode());
		userService.kickOutUser(user.getUserCode());

		loginTest(user.getUserCode(), user.getPassword());
		Subject subject = ShiroUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken(user.getUserCode(), password);
		subject.login(token);

		//登录认证成功
		boolean result= subject.isAuthenticated();
		log.info("认证结果：{}", subject.isAuthenticated());

		if(result){
			user.setLogonTime(new Date());
			userService.update(user);

			roleSet.remove(null);
			//去掉静态对象的缓存改为session存储，便于过期后内存回收
			Set<String> roleSet1 = new HashSet<>(roleSet);
			//添加用户角色名称
			List<String> roleNameSet = userService.queryRoleNamesByUser(token.getUsername());
			String roleNames = StringUtils.join(roleNameSet, ",");

			//用户所有的权限存入缓存
			Set<String> permSet = new HashSet<>();
			roleSet.forEach(roleCode->permSet.addAll(ShiroUtils.getRolePerms().get(roleCode)));

			//对外系统权限树
			if(user.getUserLevel().equals(SystemConst.OUT)){
				if(ShiroUtils.getRightTree(user.getUserCode())==null || ShiroUtils.getRightTree(user.getUserCode()).isEmpty()){
					List<PrivilegeVO> navTreeList = new ArrayList<PrivilegeVO>();
					if(roleSet.contains("mcp_hos")){
						navTreeList.addAll(permService.queryPrivList2(token.getUsername(), "410")) ;
					}else if(roleSet.contains("mcp_bank")){
						navTreeList.addAll(permService.queryPrivList2(token.getUsername(), "400")) ;
					}
					ShiroUtils.setRightTree(user.getUserCode(), navTreeList);
				}
			}

			ShiroUtils.setAttribute("user", user);
			ShiroUtils.setAttribute("org",  org);
			ShiroUtils.setAttribute("role", roleSet1);
			ShiroUtils.setAttribute("userRoleNames", roleNames);
			ShiroUtils.setAttribute("userPerms", permSet);
			ShiroUtils.setAttribute("login_type", loginType);
			ShiroUtils.setAttribute("rememberMe", true);
			ShiroUtils.setAttribute("userLevel", user.getUserLevel());


			ShiroUtils.setAttribute("sessionId", sessionId);
			ShiroUtils.setAttribute("login_token", loginToken);

			//设置session超时时间，单位：秒
//			request.getSession().setMaxInactiveInterval(timeOut);

			/***************************spring session配置*****************************************************/
			//登录成功后需要设置usercode到session表中PRINCIPAL_NAME供其它系统判断该用户是否已登录。
			ShiroUtils.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, ShiroUtils.getUserCode());
			/************************************************************************************************/
		}


		return redirectView("/login/businessRules");
	}


	@RequestMapping("dash")
	public String dash(ModelMap model) {
		String titleName = "医保贷业务系统";

//		OrgPO org = ShiroUtils.getAttribute("org");
//		if("20".equals(org.getOrgCatalog()) ){//321300
//			PfmVO pfm = ShiroUtils.getAttribute("mcp_pfm");
//			if(McpConst.VersionType.suqian.getCode().equals(pfm.getItfType())) {
//				titleName = "医惠贷业务系统";
//			}
//		}
		ShiroUtils.setAttribute("titleName", titleName);
		return "main";
	}

	@RequestMapping("/main")
	private ModelAndView main() {
		String org = ShiroUtils.getAttribute("org");

		if(org!=null) {
			return  new ModelAndView("main");
		}

		if(paramService.isDev()) {
			return new ModelAndView("index");
		}
		return redirectView("/error/notLogin");
	}

	private void loginTest(String usercode, String password) {
		SimpleAccountRealm simpleAccountRealm = new SimpleAccountRealm();
		simpleAccountRealm.addAccount(usercode, password);
		DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
		defaultSecurityManager.setRealm(simpleAccountRealm);
		SecurityUtils.setSecurityManager(defaultSecurityManager);
	}


	//用户确认业务规则
	@RequestMapping("/businessRules")
	public ModelAndView businessRules(ModelMap model, HttpSession session) {
		String view= "/login/dash";
		OrgPO org = ShiroUtils.getAttribute("org");

		if("10".equals(org.getOrgCatalog())){
			session.setAttribute("mcpName", "医保贷业务系统");
			AgreementRecordPO apo = recordService.getRecord(org.getId(), RecordService.AGREEMENT_SUQIAN);

			//存量宿迁资金方用户，在产品上线后首次登录，弹窗提示业务系统名称变更
			if(apo != null && !"1".equals(apo.getState())){
				view = "/bank/businessRules1";
			}else if(apo != null && "1".equals(apo.getState())){
				//存量宿迁资金方非首次登录不弹窗任何东西。

			}else if("321300".equals(org.getCity())){
				//增量的宿迁资金方登录不弹窗任何东西。

			}else{
				//注册地非宿迁的资金方开通权限后，首次进入医保业务系统时，弹窗确认
				AgreementRecordPO apo2 = recordService.getRecord(org.getId(), RecordService.AGREEMENT_COMMON);
				if(apo2 == null){
					view = "/bank/businessRules2";
				}
			}

		}else if("20".equals(org.getOrgCatalog())){

			//两定机构需要选择医保平台，所以先进入医保平台列表然后进行选择,随便写个公共方法先用用着，后续更改成自定义方法
			view = "/hos/miList";
		}


		return redirectView(view);
	}





	//用户无权限跳转
	@RequestMapping("/unauthorized")
	public String unauthorized(ModelMap model) {
		return  "unauthorized";
	}
	
	//用户登录后主页
	@RequestMapping("/dashboard")
	public String dashboard(ModelMap model) {
		Set<String> roleSet = ShiroUtils.getAttribute("role");
		//对外系统权限树
		if(roleSet.contains("mcp_hos")) {
			return  "/dashboard";
		}else if(roleSet.contains("mcp_bank")) {
			return  "/dashboard2";
		}else {
			return  "/dashboard";
		}
	}
	
	//用户登录后主页
	@RequestMapping("/header")
	public String header(ModelMap model) {
		UserPO user = (UserPO)ShiroUtils.getSession().getAttribute("user");
		model.put("userCode", user.getUserCode());
		return  "/include/header";
	} 
	
	//用户登录后主页
	@RequestMapping("/nav")
	public String nav(ModelMap model) {
		UserPO user = ShiroUtils.getAttribute("user");
		//Set<String> roleSet = ShiroUtils.getAttribute("role");

		model.addAttribute("navTreeList", ShiroUtils.getRightTree(user.getUserCode()));
		return  "/include/nav";
	}
	
	@RequestMapping("/logout")
	public String logout(ModelMap model) {
		Subject subject = SecurityUtils.getSubject();
		ShiroUtils.setAttribute("role", "");
		ShiroUtils.setAttribute("userPerms", "");
		subject.logout();
		if(paramService.isDev()) {
			return  "index";
		}
		return  "/base/tips/returnRfsp";
	}
	
	
	//密码处理
    String getP(String pwd) {
		StringBuilder sb1 = new StringBuilder();
		StringBuilder sb2 = new StringBuilder();
		
		int length = pwd.length();
		for(int i=0; i<length; i++) {
			sb1.append((pwd.charAt(i)-100));
		}
		pwd = sb1.toString();
		
		length = pwd.length()/2;
		for(int i=0; i<length; i++) {
			char t = (char) (Integer.parseInt(pwd.substring(i*2, i*2+2))+7);
			sb2.append(t);
		}
		return sb2.toString();
	}




    
    
	//用户登录后主页
	@RequestMapping("/err")
	public String err(ModelMap model) {
		return "base/tips/lostLogin";
	} 
    
    
    
	

}
